package hu.debrecen.adastra.card.web.social;

import hu.debrecen.adastra.card.repository.AccountRepository;
import hu.debrecen.adastra.card.repository.domain.Account;
import hu.debrecen.adastra.card.service.SocialUserService;
import hu.debrecen.adastra.card.util.SignInUtils;
import hu.debrecen.adastra.card.web.domain.UserSocialReference;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.WebRequest;

@Controller
public class SocailController {

	private static final Logger LOGGER = LoggerFactory.getLogger(SocailController.class);

	private final AuthenticationManager authenticationManager;

	private final SocialUserService socialUserService;

	private final AccountRepository accountRepository;

	@Inject
	public SocailController(final AuthenticationManager authenticationManager, final SocialUserService socialUserService, final AccountRepository accountRepository) {
		this.authenticationManager = authenticationManager;
		this.socialUserService = socialUserService;
		this.accountRepository = accountRepository;
	}

	@RequestMapping(value = "/signup", method = RequestMethod.GET)
	public String signupForm(final WebRequest request, final HttpServletRequest httpRequest) {

		SocailController.LOGGER.debug("/signup");

		Connection<?> connection = ProviderSignInUtils.getConnection(request);

		//XXX
		if (connection == null) {
			SocailController.LOGGER.warn("Connection is null, user wil be redirect to root!");
			return "redirect:.";
		}

		UserProfile userProfile = connection.fetchUserProfile();

		// Create new account

		// XXX firstname and lastname sometime is null
		String username = userProfile.getUsername();
		if (username == null) {
			username = String.format("%s%s", userProfile.getFirstName(), userProfile.getLastName());
		}

		Account account = this.accountRepository.findAccountByUsername(username);
		if (account == null) {
			account = new Account(username, userProfile.getFirstName(), userProfile.getLastName());
			SocailController.LOGGER.debug("Create new account({})", account);
			this.accountRepository.save(account);
		}

		// Sign in with new account
		SocailController.LOGGER.debug("Sign in with new account({})", account);
		SignInUtils.signin(this.authenticationManager, account.getUsername());
		ProviderSignInUtils.handlePostSignUp(account.getUsername(), request);

		UserSocialReference userSocialReference = SignInUtils.getUserSocialReference(this.socialUserService);
		SocailController.LOGGER.debug("Put userSocialReference({}) into session.", userSocialReference.getId());
		httpRequest.getSession().setAttribute("userSocialReference", SignInUtils.getUserSocialReference(this.socialUserService));

		return "redirect:/";
	}

	@RequestMapping(value = "/signin", params = { "error=provider" }, method = RequestMethod.GET)
	public String signinError(final WebRequest request, final HttpServletRequest httpRequest) {
		SocailController.LOGGER.debug("/signin error");
		return "error";
	}

}
